package com.xiaoshuidi.cloud.module.member.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.framework.security.core.util.SecurityFrameworkUtils;
import com.xiaoshuidi.cloud.module.member.controller.admin.activities.vo.ActivitiesPointVO;
import com.xiaoshuidi.cloud.module.member.controller.app.activities.vo.EnrollListVO;
import com.xiaoshuidi.cloud.module.member.controller.app.activities.vo.EnrollStatusPageVO;
import com.xiaoshuidi.cloud.module.member.controller.app.activities.vo.EnrollVO;
import com.xiaoshuidi.cloud.module.member.controller.app.activities.vo.MemberActivitiesValidCodeEnroll;
import com.xiaoshuidi.cloud.module.member.enums.WriteOffStatusEnum;
import com.xiaoshuidi.cloud.module.member.framework.sms.SmsCodeProperties;
import com.xiaoshuidi.cloud.module.member.mapper.activities.MemberActivitiesEnrollMapper;
import com.xiaoshuidi.cloud.module.member.pojo.activities.MemberActivitiesEnroll;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.hutool.core.util.RandomUtil.randomInt;

@Repository
@RequiredArgsConstructor
public class MemberActivitiesEnrollRepository extends ServiceImpl<MemberActivitiesEnrollMapper, MemberActivitiesEnroll> {
    private final MemberActivitiesEnrollMapper mapper;

    private final SmsCodeProperties smsCodeProperties;

    public Map<Long, Integer> getEnrollNum(List<Long> ids) {
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .select(MemberActivitiesEnroll::getId, MemberActivitiesEnroll::getActivityId)
                .in(MemberActivitiesEnroll::getActivityId, ids);
        List<MemberActivitiesEnroll> memberActivitiesEnrolls = mapper.selectList(wrapper);
        Map<Long, Integer> map = memberActivitiesEnrolls.stream().collect(Collectors.toMap(MemberActivitiesEnroll::getActivityId, e -> 1, Integer::sum));
        return map;
    }

    public Boolean enroll(EnrollVO vo) {
        //获取登录人
        Long userId = SecurityFrameworkUtils.getLoginUser().getId();
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getCreator, userId.toString())
                .in(MemberActivitiesEnroll::getActivityId, vo.getActivityId());
        List<MemberActivitiesEnroll> list = mapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            throw new ServiceException(400, "不允许重复报名");
        }
        MemberActivitiesEnroll enroll = new MemberActivitiesEnroll();
        enroll.setActivityId(vo.getActivityId());
        enroll.setFillItemDetail(JsonUtils.toJsonString(vo.getItems()));
        //生成随机码
        String code = String.valueOf(randomInt(smsCodeProperties.getBeginCode(), smsCodeProperties.getEndCode() + 1));
        enroll.setVerifyCode(code);
        enroll.setStatus(WriteOffStatusEnum.TO_BE_WRITTEN_OFF.getCode());
        mapper.insert(enroll);
        return true;
    }

    public Boolean enrollOrNot(Long activityId) {
        //已报名过
        Long id = SecurityFrameworkUtils.getLoginUser().getId();
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getActivityId, activityId)
                .eq(MemberActivitiesEnroll::getCreator, id);
        List<MemberActivitiesEnroll> list = mapper.selectList(wrapper);
        if (list != null && list.size() > 0) {
            return false;
        }
        return true;
    }

    public Boolean updateStatus(List<Long> ids) {
        List<MemberActivitiesEnroll> list = new ArrayList<>();
        for (Long id : ids) {
            MemberActivitiesEnroll memberActivitiesEnroll = new MemberActivitiesEnroll();
            memberActivitiesEnroll.setId(id);
            memberActivitiesEnroll.setStatus(WriteOffStatusEnum.EXPIRED.getCode());
            list.add(memberActivitiesEnroll);
        }
        mapper.updateBatch(list, list.size());
        return true;
    }

    public EnrollListVO validateExpired(Long id) {
        return mapper.validateExpired(id);
    }

    public Boolean validateCode(Long id, String verifyCode) {
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getId, id)
                .eq(MemberActivitiesEnroll::getVerifyCode, verifyCode);
        MemberActivitiesEnroll memberActivitiesEnroll = mapper.selectOne(wrapper);
        return memberActivitiesEnroll != null;
    }

    public Boolean writeOff(Long id, String verifiedBy) {
        MemberActivitiesEnroll memberActivitiesEnroll = new MemberActivitiesEnroll();
        memberActivitiesEnroll.setId(id);
        memberActivitiesEnroll.setVerifiedBy(verifiedBy);
        memberActivitiesEnroll.setStatus(WriteOffStatusEnum.WRITTEN_OFF.getCode());
        memberActivitiesEnroll.setVerifiedTime(LocalDateTime.now());
        mapper.updateById(memberActivitiesEnroll);
        return true;
    }

    public List<MemberActivitiesEnroll> getAllEnrollInfo(Long activityId) {
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getActivityId, activityId);
        return mapper.selectList(wrapper);
    }

    public List<MemberActivitiesValidCodeEnroll> getUnverified(List<Long> ids) {
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getStatus, WriteOffStatusEnum.TO_BE_WRITTEN_OFF.getCode())
                .in(MemberActivitiesEnroll::getActivityId, ids);
        return mapper.getUnverified(ids);
    }

    public List<EnrollListVO> getEnrollList(EnrollStatusPageVO form) {
        return mapper.getEnrollList(form);
    }

    public ActivitiesPointVO getActivitiesPoint(Long id) {
        return mapper.getActivitiesPoint(id);
    }

    public void updateUserId(Long oldUserId, Long userId) {
        //查看旧账号所有参加的活动
        LambdaQueryWrapper<MemberActivitiesEnroll> wrapper = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                .eq(MemberActivitiesEnroll::getCreator, oldUserId);
        List<MemberActivitiesEnroll> list = mapper.selectList(wrapper);

        if (list != null && list.size() > 0) {
            List<Long> activityIds = list.stream().map(MemberActivitiesEnroll::getActivityId).collect(Collectors.toList());

            LambdaQueryWrapper<MemberActivitiesEnroll> wp = new LambdaQueryWrapper<MemberActivitiesEnroll>()
                    .eq(MemberActivitiesEnroll::getCreator, userId)
                    .in(MemberActivitiesEnroll::getActivityId, activityIds);
            List<MemberActivitiesEnroll> list2 = mapper.selectList(wp);

            if (list2!=null&&list2.size()>0) {
                List<Long> collect = list2.stream().map(MemberActivitiesEnroll::getActivityId).collect(Collectors.toList());
                List<Long> containsCollect = activityIds.stream().filter(o -> collect.contains(o)).collect(Collectors.toList());
                List<Long> notContainsCollect = activityIds.stream().filter(o -> !collect.contains(o)).collect(Collectors.toList());

                //list2里包含的全部删除
                mapper.deleteByActivityId(containsCollect, oldUserId);
                //list2里不包含的全部替换
                mapper.updateUserId(oldUserId, userId, notContainsCollect);
            }else{
                //list2里不包含的全部替换
                mapper.updateUserId(oldUserId, userId, activityIds);
            }
        }


//        mapper.updateUserId(oldUserId,userId);
    }
}
